﻿using EnvDTE;
using EnvDTE80;
using I18nJson.Models;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Newtonsoft.Json;
using System;
using System.ComponentModel.Design;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;

namespace I18nJson
{
    /// <summary>
    /// Command handler
    /// </summary>
    internal sealed class CmdSplitToJsons
    {
        /// <summary>
        /// Command ID.
        /// </summary>
        public const int CommandId = 0x0101;

        /// <summary>
        /// Command menu group (command set GUID).
        /// </summary>
        public static readonly Guid CommandSet = new Guid("f1159795-2598-487b-bd85-5f15aef8cdc6");

        /// <summary>
        /// VS Package that provides this command, not null.
        /// </summary>
        private readonly AsyncPackage package;

        /// <summary>
        /// Initializes a new instance of the <see cref="CmdSplitToJsons"/> class.
        /// Adds our command handlers for menu (commands must exist in the command table file)
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        /// <param name="commandService">Command service to add command to, not null.</param>
        private CmdSplitToJsons(AsyncPackage package, OleMenuCommandService commandService)
        {
            this.package = package ?? throw new ArgumentNullException(nameof(package));
            commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));

            var menuCommandID = new CommandID(CommandSet, CommandId);
            var menuItem = new MenuCommand(this.Execute, menuCommandID);
            commandService.AddCommand(menuItem);
        }

        /// <summary>
        /// Gets the instance of the command.
        /// </summary>
        public static CmdSplitToJsons Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the service provider from the owner package.
        /// </summary>
        private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider
        {
            get
            {
                return this.package;
            }
        }

        /// <summary>
        /// Initializes the singleton instance of the command.
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        public static async Task InitializeAsync(AsyncPackage package)
        {
            // Switch to the main thread - the call to AddCommand in CmdSplitToJsons's constructor requires
            // the UI thread.
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);

            OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
            Instance = new CmdSplitToJsons(package, commandService);
        }

        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void Execute(object sender, EventArgs e)
        {
            string title = "拆分工程国际化配置文件";
            ThreadHelper.ThrowIfNotOnUIThread();

            var dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2;

            // 获取选中的项目
            Project project = null;
            foreach (SelectedItem item in dte2.SelectedItems)
            {
                if (item.Project != null)
                {
                    project = item.Project;
                    break;
                }
            }
            if (project == null)
            {
                VsShellUtilities.ShowMessageBox(
                    this.package,
                    "请先选择一个工程",
                    title,
                    OLEMSGICON.OLEMSGICON_INFO,
                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                return;
            }
            // 获取工程路径
            string projectPath = project.FullName.Substring(0, project.FullName.LastIndexOf(Path.DirectorySeparatorChar) + 1);
            // 生成合并后的文件名称
            string mergedJsonFullFileName = Path.Combine(projectPath, "MergedLanguageConfig.json");

            // 生成合并的文件的JSON对象
            PathedLanguageConfig[] pathedLangConfigs = null;
            using (FileStream fs = File.Open(mergedJsonFullFileName, FileMode.Open, FileAccess.Read))
            using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
            {
                string json = sr.ReadToEnd();
                pathedLangConfigs = JsonConvert.DeserializeObject<PathedLanguageConfig[]>(json);
            }
            if (pathedLangConfigs == null)
                return;
            // 保存json文件
            foreach (var pathedConfig in pathedLangConfigs)
            {
                string fullFileName = Path.Combine(projectPath, pathedConfig.Path);
                using (FileStream fs = File.Open(fullFileName, FileMode.Create, FileAccess.Write))
                using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
                {
                    string json = JsonConvert.SerializeObject(pathedConfig.Config);
                    sw.Write(json);
                    sw.Flush();
                }
                // 添加文件到项目
                project.ProjectItems.AddFromFile(fullFileName);
            }
        }
    }
}
